#include "Engine.h"

using namespace sf;

sf::RenderWindow* pApp;

jfw::Engine::Engine()
{}

/*bool jfw::Engine::LoadSettings(std::string m_sFilename,std::string m_sSeparator="=")
{
    std::fstream ConfigFile;
    ConfigFile.open(m_sFilename.c_str(), std::ios::in);
    if(ConfigFile.is_open())
    {
        std::string tmp_sLine="";
        int tmp_iSeparatorAt=0;

        while(ConfigFile.good())
            {
                getline(ConfigFile,tmp_sLine);

                tmp_iSeparatorAt = tmp_sLine.find(m_sSeparator);

                Settings.insert(std::pair<std::string,std::string>(tmp_sLine.substr(0,tmp_iSeparatorAt),
                                                                      tmp_sLine.substr(tmp_iSeparatorAt,tmp_sLine.length()-tmp_iSeparatorAt)));

                tmp_sLine="";
                tmp_iSeparatorAt=0;
            }
        ConfigFile.close();
        return true;
    }
    else
    {
        return false;
    }
}
*/
/*bool jfw::Engine::Open()
{

}*/

bool jfw::Engine::Open(int m_iWidth=1024, int m_iHeight=768, int m_iBits=32, const char* m_sTitle="", float m_fTimeStep=0.2f)
{
    pApp = new sf::RenderWindow(/*VideoMode(iWidth, iHeight, iBits), sTitle*/);
    //App.Create(VideoMode(iWidth, iHeight, iBits), sTitle/*, Style::Titlebar|Style::Close, WindowSettings(24,8,2)*/);
    pApp->Create(VideoMode(m_iWidth, m_iHeight, m_iBits), m_sTitle/*, Style::Titlebar|Style::Close, WindowSettings(24,8,2)*/);

    this->Settings.width  = m_iWidth;
    this->Settings.height = m_iHeight;
    this->Settings.bits   = m_iBits;
    this->Settings.title  = m_sTitle;
    this->Settings.time_step = m_fTimeStep;

    this->LoadContent();

    return true;
}

void jfw::Engine::LoadContent() //loads content when app is opening or it is gaining focus
{
    //Content.LoadAll();

    /*******/
    image.LoadFromFile("../../data/sprites/plane5.tga");
    test.SetImage(image);
    float scale;
    scale = (0.2f * this->Settings.height) / test.GetSize().y;
    test.Scale(scale,scale);
    /*******/
}

void jfw::Engine::UnloadContent() //unloads all content to free memory
{
    //Content.UnloadAll();
}

bool jfw::Engine::Run()
{
    float fAccumulator=0.f;
    float fElapsedTime=0.f;

    float fTime       =0.f;
    float fFps        =0.f;
    float fFrames     =0.f;

    #ifdef DEBUG
        std::cout<< "Runned1" <<std::endl;
        std::cout<< this->Settings.time_step <<std::endl;
    #endif

    while(pApp->IsOpened())
    {
        fElapsedTime = pApp->GetFrameTime();
        fElapsedTime = jfw::math::max(0.0f,fElapsedTime);

        fAccumulator += fElapsedTime;
        fAccumulator  = jfw::math::clamp(fAccumulator, 0.0f, 1.0f);

        if(fTime>0.5f)
        {
            fFps = fFrames / fTime;
            fFrames = 0.f;
            fTime   = 0.f;
            #ifdef DEBUG
                std::cout<<fFps<<std::endl;
            #endif
        }
        else
        {
            fTime += fElapsedTime;
            ++fFrames;
        }


        while (fAccumulator > this->Settings.time_step)
        {
            if(!this->Update(this->Settings.time_step))
            {
                #ifdef DEBUG
                    std::cout << "Update exited!" << std::endl;
                #endif
                return false;
            }
            fAccumulator -= this->Settings.time_step;
        }

        this->Draw();
    }
    return false;
}


bool jfw::Engine::Update(float m_fDeltaTime)
{
    while(pApp->GetEvent(Event))
    {
        if (Event.Type == Event::Closed || Event.Key.Code == Key::Escape)
        {
            #ifdef DEBUG
                std::cout << "Event: " << Event.Type << std::endl << "Exiting!" << std::endl;
            #endif
            return 0;
        }

        if (Event.Type == Event::LostFocus)
        {
            this->UnloadContent();
            #ifdef DEBUG
                std::cout << "Event: " << Event.Type << std::endl;
            #endif

        }
        else if (Event.Type == Event::GainedFocus)
        {
            this->LoadContent();
            #ifdef DEBUG
                std::cout << "Event: " << Event.Type << std::endl;
            #endif

        }
        #ifdef DEBUG
            //std::cout << "Other event: " << Event.Type << std::endl;
        #endif
    }

    jfw::GameObject::UpdateAll(m_fDeltaTime);
    return 1;

}

void jfw::Engine::Draw()
{
    pApp->Clear();

    jfw::GameObject::DrawAll();
    jfw::Player::DrawAll();

    /**********/
        pApp->Draw(test);
    /**********/

    pApp->Display();
}

void jfw::Engine::Close()
{
    if(pApp)
    {
        #ifdef DEBUG
            std::cout<<"pApp deleted!"<<std::endl;
        #endif
        pApp->Close();
        delete pApp;
    }

}

jfw::Engine::~Engine()
{
}

